<?php

namespace S\WeChat\Util;

use S\WeChat\Exception\Internal as Exception;
use S\Config as SConfig;

/**
 * 公众号工具
 *
 * 公众号是写在配置文件里面的.目前只能读取,不能修改.
 *
 * @package \Util
 */
class AccountConfigurator
{
    const OPT_NAME       = 'name';
    const OPT_TOKEN      = 'token';
    const OPT_APP_ID     = 'appid';
    const OPT_APP_SECRET = 'secret';
    const OPT_AES_KEY    = 'aes_key';
    const OPT_SERVICE_NS = 'service_namespace';

    const CONFIGURATION_FILE = 'wechat';
    const CONFIGURATION_TYPE = 'security';

    static protected $list = [];
    static protected $map  = [];

    /**
     * 获取公众号的AppID
     *
     * @param string $account 公众号的微信账号
     *
     * @return string
     */
    public static function getAppId($account)
    {
        return static::get($account, static::OPT_APP_ID);
    }

    /**
     * 获取公众号的AppSecret
     *
     * @param string $account 公众号的微信账号
     *
     * @return string
     */
    public static function getAppSecret($account)
    {
        return static::get($account, static::OPT_APP_SECRET);
    }

    /**
     * 获取EncodingAesKey
     *
     * @param string $account 公众号的微信账号
     *
     * @return array
     */
    public static function getEncodingAesKey($account)
    {
        return static::get($account, static::OPT_AES_KEY);
    }

    /**
     * 获取签名用的Token
     *
     * @param string $account 公众号的微信账号
     *
     * @return array
     */
    public static function getToken($account)
    {
        return static::get($account, static::OPT_TOKEN);
    }

    /**
     * 获取ServiceNamespace
     *
     * @param string $account 公众号的微信账号
     *
     * @return array
     */
    public static function getServiceNamespace($account)
    {
        return static::get($account, static::OPT_SERVICE_NS);
    }

    /**
     * 获取公众号详情
     *
     * @param string $account 公众号的微信账号
     *
     * @return array
     */
    public static function getDetail($account)
    {
        return static::get($account);
    }

    /**
     * 获取公众号的所有配置
     *
     * @param string $account 公众号的微信账号
     *
     * @return array
     */
    public static function getOptions($account)
    {
        return static::getDetail($account);
    }

    /**
     * 获取所有公众号的账号
     *
     * @return array
     */
    public static function getAccounts()
    {
        return array_keys(static::getMap());
    }

    /**
     * 获取公众号详情列表
     *
     * @return array
     */
    public static function getList()
    {
        if (!static::$list) {
            foreach (static::get() as $detail) {
                static::$list[] = $detail;
            }
        }
        return static::$list;
    }

    public static function getMap()
    {
        return static::get();
    }

    protected static $account_first = '';

    public static function getFirst($option = '')
    {
        if (empty(static::$account_first)) {
            static::$account_first = static::getAccounts()[0];
        }
        return static::get(static::$account_first, $option);
    }

    /**
     * 从文件获取公众号配置
     *
     * @param string $account 公众号的微信账号
     * @param string $option  配置项:为空时返回所有公众号配置
     *
     * @return array
     */
    protected static function get($account = '', $option = '')
    {
        $configuration = &SConfig::confType(static::CONFIGURATION_FILE, static::CONFIGURATION_TYPE, true);
        foreach ($configuration as $oa => &$options) {
            $options['account'] = $oa;
        }
        if ($account) {
            if (!array_key_exists($account, $configuration)) {
                (new Exception(Exception::CODE_CONF_ACCOUNT_UNDEFINED, $account))->throwMe();
            }
            $configuration = $configuration[$account];
        }
        if ($option) {
            foreach (explode('.', $option) as $i => $opt) {
                if (array_key_exists($option, $configuration)) {
                    $configuration = $configuration[$opt];
                } else {
                    (new Exception(Exception::CODE_CONF_ACCOUNT_OPTION_UNDEFINED, "{$account}.{$option}"))->throwMe();
                }
            }
        }
        return $configuration;
    }
}